TITL DAI FIRMWARE D23D-D3F3 V1.0 Rev.1 ORG :D23D * * * * ============= *** I/O HANDLER *** * ============= * * ********************* * RUN basiccmd SAVE * ********************* * * Valid as direct command and in program. * Clears the Heap, zeroes all variables, evaluate * an evt. program name and writes a file of type * 0 (BASIC) on tape. * * Exit: HL: Points to end symboltable. * DE: Length symboltable. * BC: Updated. * RSAVE CALL :CB23 Empty HEAP + symtab LHLD :02A1 Get start symtab XCHG in DE LHLD :02A3 End symtab in HL CALL :DE1A Calculate length symtab PUSH H Preserve length symtab LHLD :029F Get start textbuf XCHG in DE CALL :DE1A Calculate length textbuf PUSH H Preserve length textbuf PUSH D Preserve start textbuf CALL :E791 (0) Evaluate program name NOP NOP NOP MVI A,:30 File type byte 0 NOP NOP NOP NOP NOP NOP NOP CALL :02C5 Write fileleader, flagbyte, REM file type byte, name length REM and name. POP H Start textbuf in HL POP D Length textbuf in DE CALL :02C8 Write length and contents REM textbuf POP D Length symtab in DE JMP :D7D8 Write length and contents REM symtab + file trailer * DATA :FF * ********************* * RUN basiccmd LOAD * ********************* * * Valid as direct command and in program. * Clears Heap and all variables. Evaluates name * of program, updates BC. Required file type: 0. * C is set to print type/name or not. * A file (type 0: Basic) is read from tape. When * a file has been found, the textbuffer and the * symboltable are loaded and the pointers updated. * When loading during program run: the program * continues with the program just loaded. * * Exit: No error: BC: Updated. * DE: Begin screen RAM. * HL: End symbol table. * RLOAD CALL :CB23 Empty HEAP + symtab CALL :E791 (0) Evaluate programname PUSH B NOP NOP NOP NOP MVI B,:30 File type byte 0 PUSH H Preserve length name reqd LHLD :0100 Get CURRNT MOV A,H ORA L Load during run program? MVI C,:00 JNZ :D289 If during run; C=00 DCR C Else C=FF RLD10 POP H CALL :02CE Switch on cassette motors; REM read header + name LHLD :02A5 Get end free RAM XCHG Max. RAM in DE LHLD :029F Start textbuf in HL CALL :02D1 Load textbuffer SHLD :02A1 Store end textbuffer CC :02D1 Load symboltable CALL :D71A Store end symtab; stop REM cassette motors. POP B EI Enable interrupts JNC :D2A8 If loading error MVI A,:00 No loading error RET * ********************* * RUN LOADING ERROR * ********************* * * The programbuffers are restored. A error message * is printed. * RLERR PUSH PSW CALL :DEB5 Run 'NEW' POP PSW LXI H,:0000 SHLD :0100 Set CURRNT=0 RLEAR ADI :0B JMP :D9F5 Run 'LOADING ERROR ..' * * ****************** * OPEN TAPE FILE * ****************** * * Entry: A: File type. * HL: Points to file name. * Exit: HL: Points beyond file name. * DE: Length of name. * BC: Preserved. * A: Checksum on name. * CWOPEN PUSH PSW CALL :D720 Init. write file leader POP PSW CALL :D509 Write file type byte JMP :D7F8 Get name length, write it REM on tape, incl. its c.s. * ********************** * RUN basiccmd CHECK * ********************** * * Valid as direct command only. * Checks on file type and name. For all files * with type <3, a checksum on all data is done. * This routine remains in a endless loop and * can be aborted with BREAK only. * *RCHECK CHK10 LXI H,:0000 No program name given LXI B,:00FF Any file type NOP NOP CALL :02CE Read file header, file REM type and name; print REM type and name NOP CPI :33 JNC :D2EB If file type >=3: no check REM on checksum REM * Test checksum: REM INR C BC=0 CALL :D7E6 Set A=0, read + check REM a data block CZ :02D7 Read + check next block JNZ :D2E6 If reading error CALL :DAFF Print 'OK', car.ret DBL :DBC0 JMP :D2C3 Wait for next file REM * If checksum error: REM CHK20 CALL :DAFF Print 'BAD' DBL :DBDB CHK30 CALL :DD5E Print car.ret JMP :D2C3 Wait for next file * *********************** * WRITE BLOCK ON TAPE * *********************** * * Entry: HL: Startaddres block. * DE: Length block. * Exit: HL: 1st byte after block. * A: Checksum on block contents. * BCDE preserved. * CWBLK PUSH B PUSH D NOP CALL :D316 Write block length + REM c.s. on length MVI B,:56 Initial checksum value LD34 MOV A,D ORA E JZ :D307 If all bytes written DCX D MOV A,M Get byte of block INX H Point to next byte CALL :D30F Write byte, update checksum JMP :D2F9 Next byte REM * If all data written: write c.s. on block: REM LD35 MOV A,B Get calculated checksum CALL :D509 Write checksum NOP POP D POP B RET * ******************************* * WRITE BYTE, UPDATE CHECKSUM * ******************************* * * Entry: Byte to be written in A. * Checksum in B. * Exit: New checksum in B; A corrupted. * CDEHL preserved. * LD36 CALL :D509 Write byte XRA B RLC MOV B,A Update checksum RET * *************************************** * WRITE BLOCK LENGTH, UPDATE CHECKSUM * *************************************** * * Entry: DE: length block. * Exit: DEHL preserved. * LD37 MVI B,:56 Init checksum MOV A,D Get highest length byte, CALL :D30F write it, update c.s. MOV A,E Get lowest length byte, CALL :D30F write it, update c.s MOV A,B Get checksum CALL :D509 Write checksum on length RET REM ********************** * START FILE READING * ********************** * * Entry: HL: Address length byte of name requested. * B: File type byte requested. * C: 00 when reading during run program, * else FF. * Exit: A: File type byte. * HL: Points to 1st byte of name requested. * DE: Length name requested. * BC: preserved. * CROPEN PUSH PSW CALL :D7FF Switch cassette motors on, REM init. registers RPN10 NOP NOP NOP NOP NOP POP PSW CALL :D3F4 Read file header PUSH PSW CALL :D78A Display file type byte SUB B CALL :D3A2 Read and check header, REM program name, file type byte ORA A 0 if everything OK. JNZ :D783 If failure POP PSW RET * ************** * READ BLOCK * ************** * * Read length, contents and checksum of a block * * Entry: HL: Addr. where to dump data read. * DE: End free space. * Exit: CY=1: No error: * HL: Next free address. * BCDE preserved; AF corrupted. * CY=0: Loading error: * BCDEHL preserved. * A: Type of loading error. * CRBLK PUSH B PUSH D PUSH H CALL :D790 Calculate free RAM space XCHG Free RAM in DE CALL :D38D Read block length + c.s. REM length in HL JC :D37E If loading error 3 ORA A MVI A,:00 Loading error 0 JNZ :D380 If checksum error 0 PUSH H Save length block DAD D Calculate free RAM POP D Get length block INR A Loading error 1 POP H PUSH H Restore begin addr. JC :D380 If loading error 1 MVI B,:56 Init checksum LBK10 MOV A,D ORA E JZ :D36F If whole block read DCX D CALL :D384 Read next byte, update c.s JC :D37E If loading error 3 MOV M,A Store byte in buffer INX H JMP :D35E Next byte REM * If whole block read: REM LBK20 CALL :D4D4 Read checksum block contents JC :D37E If loading error 3 CMP B Check checksum MVI A,:02 Loading error 2 JNZ :D380 If loading error 2 JMP :C6B4 CY=1, return: no error REM * If loading error: REM LBK40 MVI A,:03 Loading error 3 LOERR ORA A JMP :C6B6 Return with CY=0: error * ********************************* * READ BYTE, CALCULATE CHECKSUM * ********************************* * * Entry: B: Checksum. * Exit: A: Byte read. * B: Updated checksum. * CDEHL preserved. * INSC CALL :D4D4 Read byte RBUEX PUSH PSW XRA B Calculate checksum RLC MOV B,A Store new value POP PSW RET * ******************** * READ NAME LENGTH * ******************** * * Entry: No conditions. * Exit: HL: Length name read. * A: Result checksum check (0 if OK). * BCDE: preserved. * CY=0: O.K.; CY=1: Out of data. * INLNG PUSH B MVI B,:56 Init. checksum CALL :D384 Read highest length byte REM and update checksum MOV H,A CNC :D384 Read lowest length byte REM and update checksum MOV L,A CNC :D4D4 Read checksum on length RHLEX PUSH PSW SUB B Check checksum MOV B,A POP PSW MOV A,B POP B RET * ******************************************* * READ + CHECK PROGRAM NAME AND FILE TYPE * ******************************************* * * Routine searches for proper file name by * reading file name and compare it with name * requested. * * Entry: A: Evt. difference in file type byte * read and requested. * B: Requested file type. * C: 00 during run program, else FF. * DE: Length requested. * HL: Address 1st byte name requested. * Exit: BCDEHL preserved. * A=0: All OK. * A=1: Loading error 1. * CMBLK PUSH B Save file type + RUN flag PUSH H Save addr reqd name MOV B,A Store deviation file type MBK10 PUSH D Save req. name length PUSH H CALL :D38D Read + check program name REM evt. c.s.failure in A JC :D3ED If reading error ORA A JNZ :D3ED If checksum error PUSH H Save length name on tape CALL :DE1A Calculate difference name REM lengths reqd and on tape MOV A,H ORA L MOV H,A Difference in H MOV L,B Difference file type in L POP D Get length name on tape MVI B,:56 Initiate checksum MBK20 XTHL Get byte reqd name MOV A,D ORA E Length name on tape = 0 ? JZ :D3D8 If length = 0, or whole REM name read. DCX D CALL :D384 Read bytes of name, update REM checksum JC :D3ED If reading error DCR C INR C Load during run? PUSH PSW Save length name on tape CNZ :D7EB Display program name POP PSW Get byte of name on tape XRA M Compare with name reqd INX H XTHL Get 'difference flag' ORA H Update it MOV H,A and store it in H JMP :D3BC Next byte REM * If whole name read: REM MBK30 CALL :D4D4 Read c.s on name contents JC :D3ED If reading error MBEX XRA B Check checksum POP H ORA L Check file type MOV L,A POP D Get length req. name MOV A,D ORA E No name requested ? JZ :D3E9 If load without name MOV A,H Difference in names? MBK40 ORA L Take also other checks in REM account MBK45 POP H POP B RET REM * If error: REM MBK50 POP H POP D MVI A,:01 Loading error 1 JMP :D3E9 * * * UNL RCHECK EQU CHK10 LST END